package com.yuyou.tas.admin.service.impl;

import com.yuyou.tas.admin.mapper.AuthOrganizationExtMapper;
import com.yuyou.tas.admin.mapper.AuthOrganizationMapper;
import com.yuyou.tas.admin.mapper.AuthOrganizationRoleRelationMapper;
import com.yuyou.tas.admin.service.*;
import com.yuyou.tas.admin.vo.req.AuthOrgan;
import com.yuyou.tas.admin.vo.req.AuthOrganPerson;
import com.yuyou.tas.admin.vo.req.AuthOrganPersonUpdate;
import com.yuyou.tas.admin.vo.req.AuthOrganUpdate;
import com.yuyou.tas.service.api.admin.dto.DtoAuthOrgan;
import com.yuyou.tas.service.api.admin.dto.DtoAuthOrganDetail;
import com.yuyou.tas.service.api.admin.dto.SimpleSubSecReqVo;
import com.yuyou.tas.service.api.admin.entity.*;
import com.yuyou.tas.service.api.lesson.service.BaseDataAPI;
import com.yuyou.tas.util.bean.EncryptVO;
import com.yuyou.tas.util.bean.LoginRedisObj;
import com.yuyou.tas.util.bean.Pagination;
import com.yuyou.tas.util.bean.ResBoolSimpleInfo;
import com.yuyou.tas.util.config.SystemConfig;
import com.yuyou.tas.util.constant.out.CommConst;
import com.yuyou.tas.util.enums.admin.AuthOrganizationEnums;
import com.yuyou.tas.util.exception.BusinessException;
import com.yuyou.tas.util.message.CommMess;
import com.yuyou.tas.util.message.admin.LoginMess;
import com.yuyou.tas.util.tool.BeanUtils;
import com.yuyou.tas.util.tool.DefindBeanUtils;
import com.yuyou.tas.util.tool.Sequence;
import com.yuyou.tas.util.tool.TokenUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
public class AuthOrganServiceImpl implements IAuthOrganService {

	@Autowired
	private AuthOrganizationMapper mapper;

	@Autowired
	private AuthOrganizationExtMapper extMapper;

	@Autowired
	private BaseDataAPI lessonApi;

	@Autowired
	private StringRedisTemplate stringRedisTemplate;

	@Autowired
	private AuthOrganizationRoleRelationMapper authOrganizationRoleRelationMapper;
	
	@Autowired
	private IAuthUserRoleRelationService authUserRoleRelationService;
	
	@Autowired
	private IAuthOrganizationFuncService authOrganizationFuncService;

	@Autowired
	private IAuthOrganizationSubSecService authOrganizationSubSecService;

	@Autowired
	private IAuthRoleService authRoleService;
	
	@Override
	@Transactional(rollbackFor=Exception.class,timeout=60)
	public ResBoolSimpleInfo addAuthOrgan(AuthOrgan authOrgan, LoginRedisObj user) throws Exception {
		ResBoolSimpleInfo info = new ResBoolSimpleInfo(true , "机构插入成功");
		Date now = new Date();

		String encrypt = TokenUtil.randomAlphabetic(20);
		String sysStr = "0001";
		Integer sysCode = mapper.getMaxSysCode();
		if(sysCode != null){
			sysStr = String.format("%04d",sysCode + 1);
		}

		//出入机构数据
		AuthOrganization auth = new AuthOrganization();
		Long id = Sequence.getSequence().nextId();//机构、机构详情统一id
		auth.setId(id);
		auth.setCreateUser(user.getUserId());//创建人
		auth.setStatus(authOrgan.getStatus());
		auth.setCreateTime(now);
		auth.setUserTimeEnd(authOrgan.getUserTimeEnd());
		auth.setUserTimeStart(authOrgan.getUserTimeStart());
		auth.setFreeAccount(authOrgan.getFreeAccount());
		auth.setType(AuthOrganizationEnums.type.institution.getValue());//机构类型为：合作机构
		auth.setCooperType(authOrgan.getCooperType());
		auth.setEncrypt(encrypt);
		auth.setSysCode(sysStr);
		mapper.insert(auth);

		//插入机构详情
		AuthOrganizationExt ext  = new AuthOrganizationExt();
		ext.setId(id);
		ext.setCreateTime(now);
		ext.setOrgHeadUrl(authOrgan.getOrgHeadUrl());
		ext.setOrgName(authOrgan.getOrgName());
		ext.setOrgIntroduce(authOrgan.getOrgIntroduce());
		ext.setOrgShortName(authOrgan.getOrgShortName());
		ext.setType(AuthOrganizationEnums.type.institution.getValue());//机构类型为：合作机构
		extMapper.insert(ext);

		//插入机构角色绑定信息
		authOrgan.getRoles().forEach(roleId -> {
			AuthOrganizationRoleRelation ao = new AuthOrganizationRoleRelation();
			ao.setAuthOrganizationId(id);
			ao.setAuthRoleId(Long.valueOf(roleId));
			ao.setCreateTime(now);
			ao.setId(Sequence.getSequence().nextId());
			authOrganizationRoleRelationMapper.insert(ao);
		});

		//讲义课件权限
		authOrgan.getOpreaTypes().forEach(t -> {
			AuthOrganizationFunc authOrganizationFunc = new AuthOrganizationFunc();
			authOrganizationFunc.setAuthOrganizationId(id);
			authOrganizationFunc.setCreateTime(now);
			authOrganizationFunc.setType(t);
			authOrganizationFunc.setId(Sequence.getSequence().nextId());
			authOrganizationFuncService.insert(authOrganizationFunc);
		});

		//插入科目年级权限
		authOrgan.getSss().forEach(simpleSubSecReqVo -> {
			simpleSubSecReqVo.getSectionId().forEach(sec -> {
				AuthOrganizationSubSec ss = new AuthOrganizationSubSec();
				ss.setAuthOrganizationId(id);
				ss.setDataSubject(simpleSubSecReqVo.getSubjectId());
				ss.setBaseSectionId(sec);
				authOrganizationSubSecService.insert(ss);
			});
		});


		//复制基础数据
		boolean result = lessonApi.copyBaseService(user.getUserId() ,user.getOrganizationId(), id);
		if(!result){
			throw new Exception(CommMess.ERR_INSIDE);
		}

		EncryptVO vo=new EncryptVO(sysStr,encrypt,id);
		stringRedisTemplate.opsForValue().set(CommConst.pre+sysStr, vo.toJson());
		return info;
	}

	@Override
	@Transactional(rollbackFor=Exception.class)
	public ResBoolSimpleInfo<String> updateAuthOrgan(AuthOrganUpdate authOrgan) {
		ResBoolSimpleInfo<String> res = new ResBoolSimpleInfo<String>();
		Date now = new Date();
		AuthOrganization auth = new AuthOrganization();
		AuthOrganizationExt ext = new AuthOrganizationExt();
		AuthOrganization authQuery = mapper.selectByPrimaryKey(authOrgan.getId());//机构
		AuthOrganizationExt extQuery = extMapper.selectByPrimaryKey(authOrgan.getId());//机构拓展
		if(authQuery != null && authQuery.getId().equals(authOrgan.getId()) && extQuery != null && extQuery.getId().equals(authOrgan.getId())){
			DefindBeanUtils.copyProperties(authOrgan , auth);
			DefindBeanUtils.copyProperties(authOrgan , ext);
			mapper.updateByPrimaryKeySelective(auth);
			extMapper.updateByPrimaryKeySelective(ext);

			//判断少了的角色，同时删除该角色的用户角色关系
			List<Long> roleIdList=authOrganizationRoleRelationMapper.selectByOrganId(authOrgan.getId());
			Map<Boolean, List<Long>> boolist=roleIdList.stream().collect(Collectors.partitioningBy(item -> authOrgan.getRoles().contains(item)));
			List<Long> lessRoleIdList=boolist.get(false);


			if(CollectionUtils.isNotEmpty(lessRoleIdList)){

				//zy业务平台的机构不能删除某些角色
				if(SystemConfig.zyOrganList.contains(authQuery.getSysCode())){
					List<AuthRole> autuRoleList=authRoleService.findByIds(lessRoleIdList);
					for(AuthRole role:autuRoleList){
						if(SystemConfig.initOrganRoleType.contains(role.getRoleType())){
							throw new BusinessException("不能删除机构角色");
						}
					}
				}

				//删除该机构角色id的用户角色关系
				List<AuthUserRoleRelation> delList=authUserRoleRelationService.findByRole7Organ(lessRoleIdList, authOrgan.getId());
				if(CollectionUtils.isNotEmpty(delList)){
					authUserRoleRelationService.delByIds(delList.stream().map(item->item.getId()).collect(Collectors.toList()));
				}	
			}
			
			//删除角色绑定旧数据
			authOrganizationRoleRelationMapper.deletedByOrganId(authOrgan.getId());

			//重新添加角色绑定信息
			authOrgan.getRoles().forEach(roleId -> {
				AuthOrganizationRoleRelation ao = new AuthOrganizationRoleRelation();
				ao.setCreateTime(now);
				ao.setAuthRoleId(Long.valueOf(roleId));
				ao.setAuthOrganizationId(authOrgan.getId());
				ao.setId(Sequence.getSequence().nextId());
				authOrganizationRoleRelationMapper.insert(ao);
			});


			//删除讲义课件权限
			authOrganizationFuncService.delByOrganId(authOrgan.getId());

			//讲义课件权限
			authOrgan.getOpreaTypes().forEach(t -> {
				AuthOrganizationFunc authOrganizationFunc = new AuthOrganizationFunc();
				authOrganizationFunc.setAuthOrganizationId(authOrgan.getId());
				authOrganizationFunc.setCreateTime(now);
				authOrganizationFunc.setType(t);
				authOrganizationFunc.setId(Sequence.getSequence().nextId());
				authOrganizationFuncService.insert(authOrganizationFunc);
			});

			//删除科目年级权限
			authOrganizationSubSecService.delAllByOrganId(authOrgan.getId());

            //插入科目年级权限
            authOrgan.getSss().forEach(simpleSubSecReqVo -> {
                simpleSubSecReqVo.getSectionId().forEach(sec -> {
                    AuthOrganizationSubSec ss = new AuthOrganizationSubSec();
                    ss.setAuthOrganizationId(authOrgan.getId());
                    ss.setDataSubject(simpleSubSecReqVo.getSubjectId());
                    ss.setBaseSectionId(sec);
                    authOrganizationSubSecService.insert(ss);
                });
            });

			res.setMessage("更新成功");
			res.setSuccess(true);
		}
		return res;
	}

	@Override
	@Transactional(rollbackFor=Exception.class,timeout=60)
	public ResBoolSimpleInfo delAuthOrgan(Long id) {
		AuthOrganization authOrganization=mapper.selectByPrimaryKey(id);
		//zy业务平台的机构不能删除某些角色
		if(SystemConfig.zyOrganList.contains(authOrganization.getSysCode())){
			throw new BusinessException("不能删除机构");
		}
		
		mapper.deleteByPrimaryKey(id);
		extMapper.deleteByPrimaryKey(id);

		//删除角色绑定旧数据
		authOrganizationRoleRelationMapper.deletedByOrganId(id);
        //删除讲义课件权限
        authOrganizationFuncService.delByOrganId(id);
		//删除科目年级权限
		authOrganizationSubSecService.delAllByOrganId(id);
        /*//删除旧年级权限
        authOrganizationPermitService.delOrganPermitWithType(id , AuthOrganizationPermitEnums.TYPE.SEC.getValue());
        //删除旧科目权限
        authOrganizationPermitService.delOrganPermitWithType(id , AuthOrganizationPermitEnums.TYPE.SUB.getValue());*/

		ResBoolSimpleInfo info = new ResBoolSimpleInfo(true , "删除成功");
		return info;
	}

	@Override
	@Transactional(rollbackFor=Exception.class,timeout=60)
    public ResBoolSimpleInfo addAuthOrganPerson(AuthOrganPerson authOrgan, LoginRedisObj user) throws Exception {
        ResBoolSimpleInfo info = new ResBoolSimpleInfo(true , "个人合作插入成功");
        Date now = new Date();

		String encrypt = TokenUtil.randomAlphabetic(20);
		String sysStr = "0001";
		Integer sysCode = mapper.getMaxSysCode();
		if(sysCode != null){
			sysStr = String.format("%04d",sysCode + 1);
		}

        //出入机构数据
		AuthOrganization auth = new AuthOrganization();
        Long id = Sequence.getSequence().nextId();//机构、机构详情统一id
        auth.setId(id);
        auth.setCreateUser(user.getUserId());//创建人
        auth.setStatus(authOrgan.getStatus());
        auth.setCreateTime(now);
        auth.setUserTimeEnd(authOrgan.getUserTimeEnd());
        auth.setUserTimeStart(authOrgan.getUserTimeStart());
        auth.setFreeAccount(authOrgan.getFreeAccount());
        auth.setType(AuthOrganizationEnums.type.person.getValue());//机构类型为：合作个人
		auth.setCooperType(authOrgan.getCooperType());
		auth.setEncrypt(encrypt);
		auth.setSysCode(sysStr);
        mapper.insert(auth);

        //插入机构详情
        AuthOrganizationExt ext  = new AuthOrganizationExt();
        ext.setId(id);
        ext.setCreateTime(now);
        ext.setPerName(authOrgan.getPerName());
        ext.setPerPhone(authOrgan.getPerPhone());
        ext.setType(AuthOrganizationEnums.type.person.getValue());//机构类型为：合作机构
        extMapper.insert(ext);

		//插入机构角色绑定信息
		authOrgan.getRoles().forEach(roleId -> {
			AuthOrganizationRoleRelation ao = new AuthOrganizationRoleRelation();
			ao.setAuthOrganizationId(id);
			ao.setAuthRoleId(Long.valueOf(roleId));
			ao.setCreateTime(now);
			ao.setId(Sequence.getSequence().nextId());
			authOrganizationRoleRelationMapper.insert(ao);
		});

		//讲义课件权限
		authOrgan.getOpreaTypes().forEach(t -> {
			AuthOrganizationFunc authOrganizationFunc = new AuthOrganizationFunc();
			authOrganizationFunc.setAuthOrganizationId(id);
			authOrganizationFunc.setCreateTime(now);
			authOrganizationFunc.setType(t);
			authOrganizationFunc.setId(Sequence.getSequence().nextId());
			authOrganizationFuncService.insert(authOrganizationFunc);
		});

        //插入科目年级权限
        authOrgan.getSss().forEach(simpleSubSecReqVo -> {
            simpleSubSecReqVo.getSectionId().forEach(sec -> {
                AuthOrganizationSubSec ss = new AuthOrganizationSubSec();
                ss.setAuthOrganizationId(id);
                ss.setDataSubject(simpleSubSecReqVo.getSubjectId());
                ss.setBaseSectionId(sec);
                authOrganizationSubSecService.insert(ss);
            });
        });


		//复制基础数据
		boolean result = lessonApi.copyBaseService(user.getUserId() ,user.getOrganizationId(), id);
		if(!result){
			throw new Exception(CommMess.ERR_INSIDE);
		}

		EncryptVO vo=new EncryptVO(sysStr,encrypt,id);
		stringRedisTemplate.opsForValue().set(CommConst.pre+sysStr, vo.toJson());
        return info;
    }

	@Override
	@Transactional(rollbackFor=Exception.class,timeout=60)
	public ResBoolSimpleInfo updateAuthOrganPerson(AuthOrganPersonUpdate authPersonOrgan) {
		ResBoolSimpleInfo res = new ResBoolSimpleInfo();
		Date now = new Date();
		AuthOrganization auth = new AuthOrganization();
		AuthOrganizationExt ext = new AuthOrganizationExt();
		AuthOrganization authQuery = mapper.selectByPrimaryKey(authPersonOrgan.getId());//机构
		AuthOrganizationExt extQuery = extMapper.selectByPrimaryKey(authPersonOrgan.getId());//机构拓展
		if(authQuery != null && authQuery.getId().equals(authPersonOrgan.getId()) && extQuery != null && extQuery.getId().equals(authPersonOrgan.getId())){
			DefindBeanUtils.copyProperties(authPersonOrgan , auth);
			DefindBeanUtils.copyProperties(authPersonOrgan , ext);
			mapper.updateByPrimaryKeySelective(auth);
			extMapper.updateByPrimaryKeySelective(ext);

			//判断少了的角色，同时删除该角色的用户角色关系
			List<Long> roleIdList=authOrganizationRoleRelationMapper.selectByOrganId(authPersonOrgan.getId());
			Map<Boolean, List<Long>> boolist=roleIdList.stream().collect(Collectors.partitioningBy(item -> authPersonOrgan.getRoles().contains(item)));
			List<Long> lessRoleIdList=boolist.get(false);

			if(CollectionUtils.isNotEmpty(lessRoleIdList)){

                //zy业务平台的机构不能删除某些角色
                if(SystemConfig.zyOrganList.contains(authQuery.getSysCode())){
                    List<AuthRole> autuRoleList=authRoleService.findByIds(lessRoleIdList);
                    for(AuthRole role:autuRoleList){
                        if(SystemConfig.initOrganRoleType.contains(role.getRoleType())){
                            throw new BusinessException("不能删除机构角色");
                        }
                    }
                }

                //删除该机构角色id的用户角色关系
                List<AuthUserRoleRelation> delList=authUserRoleRelationService.findByRole7Organ(lessRoleIdList, authPersonOrgan.getId());
                if(CollectionUtils.isNotEmpty(delList)){
                    authUserRoleRelationService.delByIds(delList.stream().map(item->item.getId()).collect(Collectors.toList()));
                }
            }


			//删除角色绑定旧数据
			authOrganizationRoleRelationMapper.deletedByOrganId(authPersonOrgan.getId());

			//重新添加角色绑定信息
			authPersonOrgan.getRoles().forEach(roleId -> {
				AuthOrganizationRoleRelation ao = new AuthOrganizationRoleRelation();
				ao.setCreateTime(now);
				ao.setAuthRoleId(Long.valueOf(roleId));
				ao.setAuthOrganizationId(authPersonOrgan.getId());
				ao.setId(Sequence.getSequence().nextId());
				authOrganizationRoleRelationMapper.insert(ao);
			});

			//删除讲义课件权限
			authOrganizationFuncService.delByOrganId(authPersonOrgan.getId());

			//讲义课件权限
			authPersonOrgan.getOpreaTypes().forEach(t -> {
				AuthOrganizationFunc authOrganizationFunc = new AuthOrganizationFunc();
				authOrganizationFunc.setAuthOrganizationId(authPersonOrgan.getId());
				authOrganizationFunc.setCreateTime(now);
				authOrganizationFunc.setType(t);
				authOrganizationFunc.setId(Sequence.getSequence().nextId());
				authOrganizationFuncService.insert(authOrganizationFunc);
			});


            //删除科目年级权限
            authOrganizationSubSecService.delAllByOrganId(authPersonOrgan.getId());

            //插入科目年级权限
            authPersonOrgan.getSss().forEach(simpleSubSecReqVo -> {
                simpleSubSecReqVo.getSectionId().forEach(sec -> {
                    AuthOrganizationSubSec ss = new AuthOrganizationSubSec();
                    ss.setAuthOrganizationId(authPersonOrgan.getId());
                    ss.setDataSubject(simpleSubSecReqVo.getSubjectId());
                    ss.setBaseSectionId(sec);
                    authOrganizationSubSecService.insert(ss);
                });
            });


			res.setMessage("更新成功");
			res.setSuccess(true);
		}
		return res;
	}

	@Override
	public ResBoolSimpleInfo<DtoAuthOrganDetail> getByID(Long id) {
		AuthOrganization ao = mapper.selectByPrimaryKey(id);
		if(ao == null){return new ResBoolSimpleInfo(true , "没有该机构记录" , null);}
		AuthOrganizationExt aoe = extMapper.selectByPrimaryKey(id);
		DtoAuthOrganDetail detail = new DtoAuthOrganDetail();
		DefindBeanUtils.copyProperties(aoe , detail);
		DefindBeanUtils.copyProperties(ao , detail);

		detail.setRoles(authOrganizationRoleRelationMapper.selectByOrganId(id));
		detail.setOpreaTypes(authOrganizationFuncService.getByOrganId(id));//讲义课件权限

		List<AuthOrganizationSubSec> ssList = authOrganizationSubSecService.getAllByOrganId(id);
		Map<Long , List<AuthOrganizationSubSec>> ssMap = BeanUtils.toGroup(ssList , "dataSubject");
		List<SimpleSubSecReqVo> subSecs = new ArrayList<>();
		ssMap.forEach((key, value) -> {
			SimpleSubSecReqVo simpleSubSecReqVo = new SimpleSubSecReqVo();
			simpleSubSecReqVo.setSubjectId(key);
			simpleSubSecReqVo.setSectionId(value.stream().map(item -> item.getBaseSectionId()).collect(Collectors.toList()));
			subSecs.add(simpleSubSecReqVo);
		});
		detail.setSubSec(subSecs);


		ResBoolSimpleInfo res = new ResBoolSimpleInfo(true , null , detail);
		return res;
	}

	@Override
	public int findOrgPageCount(Pagination<DtoAuthOrgan> p) {
		return extMapper.findOrgPageCount(p);
	}

	@Override
	public List<DtoAuthOrgan> findOrgPageList(Pagination<DtoAuthOrgan> p) {
		List<DtoAuthOrgan> list = extMapper.findOrgPageList(p);
		Date today = new Date();
		list.forEach((DtoAuthOrgan a) -> {//设置状态具体内容
			if(today.after(a.getUserTimeEnd()) || today.before(a.getUserTimeStart())){//有效期前后都为已终止
				a.setStatusStr(AuthOrganizationEnums.statusStr.getName(a.getStatus()) + "(" + AuthOrganizationEnums.statusStr.getName(3) + ")");
			}else{
				a.setStatusStr(AuthOrganizationEnums.statusStr.getName(a.getStatus()));
			}
		});
		return list;
	}

	@Override
	public List<AuthOrganization> selectAll() {
		return mapper.selectAll();
	}

	@Override
	public AuthOrganization selectByPrimaryKey(Long id) {
		return mapper.selectByPrimaryKey(id);
	}

	@Override
	public List<AuthOrganizationExt> findActiveOrganByAcc(String account) {
		List<AuthOrganizationExt> exsList=extMapper.findActiveOrganByAcc(account);
		
		exsList=exsList.stream().filter(item ->{		
			return validateOrganAcc(item.getId()).isSuccess();
		}).collect(Collectors.toList());

		//个人机构，名称复制至机构名称
		exsList.forEach(e ->{
			if(AuthOrganizationEnums.type.person.getValue() == e.getType()){
				e.setOrgName(e.getPerName());
			}
		});
		return exsList;
	}
	
	
	@Override
	public ResBoolSimpleInfo<String> validateOrganAcc(Long authOrganizationId){
		ResBoolSimpleInfo<String> res=new ResBoolSimpleInfo<String>();
		//判断机构账号有效期
		if(!authOrganizationId.equals(SystemConfig.SYS_ORGAN_ID)){
			AuthOrganization authOrganization=this.selectByPrimaryKey(authOrganizationId);					
			if(authOrganization.getStatus()==AuthOrganizationEnums.status.end.getValue()){
				res.setSuccess(false);
				res.setMessage(LoginMess.ERR_ORGAN_FREEZE);
				return res;
			}else{
				Date now =new Date();
				if(authOrganization.getUserTimeStart().getTime()>now.getTime() || authOrganization.getUserTimeEnd().getTime() < now.getTime()){
					res.setSuccess(false);
					res.setMessage(LoginMess.ERR_ORGAN_EXPIRE);
					return res;
				}
			}
		}
		res.setSuccess(true);
		return res;
	}

	@Override
	public List<AuthOrganizationExt> findOrganByAcc(String account) {
		return extMapper.findOrganByAcc(account);
	}
	
	
	
	
	
	
	
	
	
	
	
}